<!-- 定制上传组件，仅用于非自动上传 -->
<template>
    <div class="custom-upload-wrap">
        <t-button
            variant="outline"
            theme="default"
            class="manual-upload-btn"
            @click="manualUpload"
        >
            <template #icon>
                <Upload1Icon />
            </template>
            点击上传
        </t-button>
        <t-upload
            v-bind="options"
            ref="uploadRef"
            v-model="uploadFiles"
            class="custom-upload"
            theme="custom"
            draggable
            :auto-upload="false"
            :before-all-files-upload="beforeAllFilesUpload"
            :style="myStyle"
            @dragenter="handleDragenter"
            @drop="fileDrop"
            @change="fileChange"
        >
            <template #dragContent="params">
                <div
                    v-if="uploadFiles.length"
                    @click="e => e.stopPropagation()"
                >
                    <t-table
                        :data="uploadFiles"
                        :columns="showColumns"
                        max-height="400"
                        @click="handleUploadTableClick"
                    >
                        <template #size="{row}">
                            <span>{{ getFileSize(row.size) }}</span>
                        </template>
                        <template #action="option">
                            <t-link
                                theme="danger"
                                hover="color"
                                @click="() => handleRemoveFile(option)"
                            >
                                删除
                            </t-link>
                        </template>
                    </t-table>
                </div>
                <template v-else>
                    <p v-if="params && params.dragActive">释放鼠标</p>
                    <p v-else-if="innerText">
                      {{ innerText }}
                    </p>
                    <p v-else>将 <span class="font-bold">文件</span> 或 <span class="font-bold">文件夹</span> 拖拽 到此处上传</p>
                </template>
            </template>
        </t-upload>
    </div>
</template>

<script setup>
import { nextTick, ref, computed, defineExpose, watch } from 'vue';
import dayjs from 'dayjs';
import { Upload1Icon } from 'tdesign-icons-vue-next';
import useBatchUpload from '@/hooks/useBatchUpload';

const props = defineProps({
    options: {
        type: Object,
        default: () => ({
            multiple: true
        })
    },
    modelValue: {
        type: Array,
        default: () => []
    },
    myStyle: {
        type: Object,
        default: () => ({
            width: '100%'
        })
    },
    expandFolder: {
        type: Boolean,
        default: false
    },
    mode: {
        type: String,
        default: 'common'
    },
    innerText:{
        type:String,
        default:""
    }
})

const emits = defineEmits(['change', 'remove', 'update:modelValue'])

const baseColumns = [
    {
        title: '文件名',
        colKey: 'name',
        align: 'center',
        width: 100,
        ellipsis: true
    },
    {
        title: '文件大小',
        colKey: 'size',
        align: 'center',
        width: 40
    },
    {
        title: '操作',
        colKey: 'action',
        align: 'center',
        width: '40'
    }
]
const showColumns = computed(() => {
    const cacheColumns = [...baseColumns]
    if (props.mode === 'moreRoleData') {
        cacheColumns.splice(1, 0, {
            title: '所属票数',
            colKey: 'subjectNo',
            align: 'center',
            width: 40
        })
    }
    return cacheColumns
})

const { checkFileType, checkFileSizeInRange, scanFiles, addFiles, removeFile, resetFileList, fileList } = useBatchUpload({
    callback: (val) => {
        uploadFiles.value = val
        isDrop.value = false;
        nextTick(() => {
            emits('change', val)
        })
    }
});

const uploadFiles = computed({
    get() {
        return props.modelValue
    },
    set(val) {
        let cacheVal = val
        if (props.expandFolder) {
            const arr = [];
            val.forEach(item => {
                if (item.children) {
                    arr.push(...item.children)
                } else {
                    arr.push(item)
                }
            })
            cacheVal = arr;
        }
        emits('update:modelValue', cacheVal)
    }
});

watch(() => uploadFiles.value, (newVal, oldVal) => {
    if (oldVal.length && !newVal.length) {
        // 重置文件列表
        resetFileList();
    }
})

const isDrop = ref(false);
const uploadRef = ref(null)

const getFileSize = (size) => {
    const kbNum = size / 1000;
    const mbNum = size / (1000 * 1024);
    const gNum = size / (1000 * 1024 * 1024);
    const tNum = size / (1000 * 1024 * 1024 * 1024);
    if (tNum > 1) {
        return `${ tNum.toFixed(2) } T`
    } if (
        gNum > 1
    ) {
        return `${ gNum.toFixed(2) } G`
    } if (mbNum > 1) {
        return `${ mbNum.toFixed(1) } MB`
    } if (kbNum > 1) {
        return `${ kbNum.toFixed(0) } KB`
    }
    return `${ size } Bytes`
}

const fileDrop = ({ e }) => {
    if(props.options.multiple===false){
      return
    }
    const { items } = e.dataTransfer;
    if (items) {
        isDrop.value = true
        scanFiles(items)
    }
}

const handleDragenter = () => {
}

const fileChange = (files, context) => {
    const manualSelectFiles = []; // 点击选择按钮选中上传的文件
    const newFiles = [];
    files.forEach(f => {
        const isHideFile = !f.name?.split('.')[0]
        if (!f.trigger && !isHideFile && !isDrop.value) {
            const newF = {
                ...f,
                trigger: 'select',
                status: 'success',
                uploadTime: dayjs(f.lastModified).format('YYYY-MM-DD HH:mm')
            }
            const hasUpload = fileList.value.some(file => file.name === f.name)
            if (!hasUpload) {
                manualSelectFiles.push(newF)
                newFiles.push(newF)
            }
        } else if (!isHideFile && !isDrop.value) {
            newFiles.push(f)
        }
    })
    if (manualSelectFiles.length) {
        addFiles(manualSelectFiles)
    }
    if (!isDrop.value) {
        uploadFiles.value = newFiles;
        emits('change', newFiles)
    }
}

const beforeAllFilesUpload = (files) => {
    const inRange = checkFileSizeInRange(files);
    if (!inRange) {
        return false;
    }
    const isAllowType = checkFileType(files, true, false);
    if (!isAllowType) {
        return false;
    }
    return true;
}

const handleRemoveFile = ({ row, rowIndex }) => {
    removeFile(rowIndex)
    uploadFiles.value.splice(rowIndex, 1)
    nextTick(() => {
        emits('change', uploadFiles.value)
        emits('remove', uploadFiles.value)
    })
}

// 点击上传按钮
const manualUpload = () => {
    uploadRef.value.triggerUpload();
}

const reset = () => {
    resetFileList()
}

defineExpose({
    reset
})
</script>

<style>
.t-upload__dragger-center{
    width:100%
}
</style>

<style lang="less" scoped>
.custom-upload-wrap{
    width: 100%;
}
.manual-upload-btn{
    margin-bottom: 12px;
}
</style>
